package com.xuan.yrmanage.common.exception;

import com.google.common.collect.ImmutableMap;
import com.xuan.yrmanage.common.response.CommonCode;
import com.xuan.yrmanage.common.response.ResponseResult;
import com.xuan.yrmanage.common.response.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


/**
 * FileName: ExceptionCatch
 * Author:   xuan zongjun
 * Date:     2020/2/26 8:52
 * Description: 控制器增强类，捕获系统异常
 */

@ControllerAdvice
public class ExceptionCatch {
    private static  final Logger LOGGER = LoggerFactory.getLogger( ExceptionCatch.class );
    //使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点的一旦创建不可改变，并且线程安全
    private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
    //使用builder来构建一个异常类型和错误代码的异常
    private static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();

    static {
        //在这里加入一些基础的异常类型判断
        builder.put( HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM );
        builder.put( HttpRequestMethodNotSupportedException.class,CommonCode.REQUEST_METHOD_NOT_SUPPORT );
    }


    //捕获 CustomException异常 ExceptionHandler 括号中的参数指定要捕获的异常类型
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseResult customException(CustomException e){
        //此错误信息打印在控制台
        LOGGER.error( "catch exception : {}\r\nexception: ",e.getMessage(), e );
        ResultCode resultCode =  e.getResultCode();
        //把resultCode里面的code \success\message  给 ResponseResult的code \success\message
        ResponseResult responseResult =new ResponseResult( resultCode );
        return responseResult;

    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception exception){
        //记录日志；
        LOGGER.error( "catch exception:{}",exception.getMessage() );
        if(EXCEPTIONS==null){
            EXCEPTIONS = builder.build();
        }
       final ResultCode resultCode = EXCEPTIONS.get( exception.getClass() );
        final ResponseResult responseResult;
        if(resultCode!=null){
            responseResult = new ResponseResult( resultCode );
        }else{
            responseResult = new ResponseResult( CommonCode.SERVER_ERROR );
        }

        return responseResult;

    }



}
